using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;

namespace wMobinium.core.test
{
    [NUnit.Framework.TestFixture]
    public class TestPackageTest
    {
        private TestPackage testPackage = new TestPackage();

        [NUnit.Framework.TestFixtureSetUp]
        public void TestFixtureSetUp()
        {
            testPackage = CreateTestPackage();
        }

        public TestPackage CreateTestPackage()
        {
            TestPackage package = new TestPackage();
            TestPackageClass testClass1 =
                CreateTestClass("NameTest", "ensureNameIsEqual", "ensureNullNameIsNotEqualToName");
            TestPackageClass testClass2 =
                CreateTestClass("OutlookContactTest", "ensureContactIsEqual", "ensureNullContactIsNotEqualToContact");

            TestPackageAssembly testPackageAssembly =
                CreateTestAssembly("OutlookContacts.Tests", "OutlookContacts.Tests.dll", testClass1, testClass2);

            package.Name = "My first test suite";
            package.TestAssemblies.Add(testPackageAssembly);

            return package;
        }

        [NUnit.Framework.Test]
        public void EnsureTestMethodEqualityWorks()
        {
            TestPackageMethod testPackageMethod = CreateTestMethod("MethodName");
            TestPackageMethod otherTestPackageMethod = CreateTestMethod("MethodName");

            Assert.AreEqual(testPackageMethod, testPackageMethod);
            Assert.AreNotEqual(testPackageMethod, null);
            Assert.AreNotEqual(testPackageMethod, new TestPackageClass());
            Assert.AreEqual(testPackageMethod, otherTestPackageMethod);
        }

        [NUnit.Framework.Test]
        public void EnsureTestClassEqualityWorks()
        {
            TestPackageClass testPackageClass = CreateTestClass("Class1", "MethodName1", "MethodName2");
            TestPackageClass otherTestPackageClass = CreateTestClass("Class1", "MethodName1", "MethodName2");

            Assert.AreEqual(testPackageClass, testPackageClass);
            Assert.AreNotEqual(testPackageClass, null);
            Assert.AreNotEqual(testPackageClass, new TestPackageAssembly());
            Assert.AreEqual(testPackageClass, otherTestPackageClass);
        }

        [NUnit.Framework.Test]
        public void EnsureTestAssemblyEqualityWorks()
        {
            TestPackageAssembly testPackageAssembly =
                CreateTestAssembly("AssemblyName1", "FileName1", CreateTestClass("Class1", "MethodName1", "MethodName2"),
                                   CreateTestClass("Class2", "MethodName11", "MethodName12"));
            TestPackageAssembly othertestPackageAssembly =
                CreateTestAssembly("AssemblyName1", "FileName1", CreateTestClass("Class1", "MethodName1", "MethodName2"),
                                   CreateTestClass("Class2", "MethodName11", "MethodName12"));

            Assert.AreEqual(testPackageAssembly, testPackageAssembly);
            Assert.AreNotEqual(testPackageAssembly, null);
            Assert.AreNotEqual(testPackageAssembly, new TestPackageClass());
            Assert.AreEqual(testPackageAssembly, othertestPackageAssembly);
        }

        [NUnit.Framework.Test]
        public void EnsureTestDataIsSerialized()
        {
            string fileName = @"C:\xml.xml";
            SerializeTestSuite(fileName, testPackage);

            Trace.WriteLine(testPackage.ToString());
        }

        [NUnit.Framework.Test]
        public void EnsureTestDataIsDeSerialized()
        {
            string fileName = @"C:\newxml.xml";
            XmlSerializer xmlSerializer = new XmlSerializer(typeof (TestPackage));

            SerializeTestSuite(fileName, testPackage);

            TextReader textReader = new StreamReader(fileName);
            TestPackage returnedTestPackage = (TestPackage) xmlSerializer.Deserialize(textReader);

            Assert.AreEqual(testPackage, returnedTestPackage);
        }

        public TestPackageAssembly CreateTestAssembly(string assemblyName1, string fileName1,
                                                      TestPackageClass testClass1, TestPackageClass testClass2)
        {
            TestPackageAssembly testPackageAssembly = new TestPackageAssembly();
            testPackageAssembly.Name = assemblyName1;
            testPackageAssembly.FileName = fileName1;
            testPackageAssembly.DesktopPath = @"..\..\..\MockAssembly\outlookContacts.Tests\bin\Debug\";
            testPackageAssembly.TestClasses.Add(testClass1);
            testPackageAssembly.TestClasses.Add(testClass2);
            return testPackageAssembly;
        }

        public TestPackageClass CreateTestClass(string className, params string[] testMethods)
        {
            TestPackageClass testPackageClass = new TestPackageClass();
            testPackageClass.TestMethods = new List<TestPackageMethod>();
            testPackageClass.Name = className;

            foreach (string testMethod in testMethods)
                testPackageClass.TestMethods.Add(CreateTestMethod(testMethod));

            return testPackageClass;
        }

        public TestPackageClass CreateTestClass(string className, string testMethodName1, string testMethodName2)
        {
            return CreateTestClass(className, new string[] {testMethodName1, testMethodName2});
        }

        public TestPackageMethod CreateTestMethod(string expectedMethodName)
        {
            TestPackageMethod testPackageMethod = new TestPackageMethod();
            testPackageMethod.Name = expectedMethodName;
            return testPackageMethod;
        }

        public void SerializeTestSuite(string fileName, TestPackage package)
        {
            DeleteFile(fileName);

            XmlSerializer xmlSerializer = new XmlSerializer(typeof (TestPackage));
            TextWriter textWriter = new StreamWriter(fileName);

            xmlSerializer.Serialize(textWriter, package);
            textWriter.Close();
        }

        public void DeleteFile(string fileName)
        {
            FileInfo xmlFile = new FileInfo(fileName);
            if (xmlFile.Exists)
                xmlFile.Delete();
        }
    }
}